import os

filename = "student.txt"

"""
author: wiggins
date: 2023-4-26
des: 学生信息管理系统，该系统可以帮助教师快速录入学生的信息，
    并且对学生的信息进行基本的增、删、改、查操作；还可以根据排序功能，
    宏观地看到学生成绩从高到低的排列，随时掌握学生近期的学习状态。
    实时地将学生的信息保存到磁盘文件中，方便查看。
"""


def main():
    ctrl = True  # 标记是否退出系统
    while ctrl:
        menu()  # 显示菜单
        option_str = input("请选择：")  # 选择菜单项

        option_list = ["0", "1", "2", "3", "4", "5", "6", "7"]  # 系统支持的功能枚举
        if option_str in option_list:
            option_int = int(option_str)

            if option_int == 0:
                print("您已退出学生信息管理")
                ctrl = False

            elif option_int == 1:
                insert()

            elif option_int == 2:
                search()

            elif option_int == 3:
                delete()

            elif option_int == 4:
                modify()

            elif option_int == 5:
                sort()

            elif option_int == 6:
                total()

            elif option_int == 7:
                show()


def menu():
    # 输出菜单03
    print('''
    ╔————————————————学生信息管理系统——————————————╗
    │                                           │
    │                                           │
    │   =============== 功能菜单 ===============  │
    │                                           │
    │   1 录入学生信息                            │
    │   2 查找学生信息                            │
    │   3 删除学生信息                            │
    │   4 修改学生信息                            │
    │   5 排序                                   │
    │   6 统计学生总人数                           │ 
    │   7 显示所有学生信息                         │
    │   0 退出系统                               │
    │  ======================================== │
    │  说明：通过数字或↑↓方向键选择菜单               │
    ╚———————————————————————————————————————————╝
    ''')


def insert():
    student_list = []  # 保存学生信息的列表
    mark = True  # 是否继续添加

    while mark:
        stu_id = input("请输入ID（如1001）：")
        if not stu_id:  # ID为空，跳出循环
            break

        name = input("请输入名字：")
        if not name:
            break

        try:
            english = int(input("请输入英语成绩："))
            python = int(input("请输入Python成绩："))
            c = int(input("请输入C语言成绩："))
        except ValueError:
            print("输入无效，不是整型数值. . . .重新录入信息")
            continue

        student = {  # 将输入的学生信息保存到字典
            "id": stu_id,
            "name": name,
            "english": english,
            "python": python,
            "c": c
        }

        student_list.append(student)  # 将学生信息字典保存到列表

        input_mark = input("是否继续添加？（y/n）:")

        if input_mark == "y":
            mark = True
        else:  # 不继续添加
            mark = False

    __save(student_list)  # 将学生信息保存到文件
    print("学生信息录入完毕")


def search():
    mark = True
    student_query = []
    while mark:
        stu_id = ""
        stu_name = ""
        if os.path.exists(filename):
            mode = input("按ID查输入1；按姓名查输入2：")
            if mode == "1":
                stu_id = input("请输入学生ID：")

            elif mode == "2":
                stu_name = input("请输入学生姓名：")

            else:
                print("您的输入有误，请重新输入！")
                search()

            with open(filename, "r") as f:
                students = f.readlines()
                for s in students:
                    d = dict(eval(s))
                    if stu_id != "" and d["id"] == stu_id:
                        student_query.append(d)
                    elif stu_name != "" and d["name"] == stu_name:
                        student_query.append(d)
            __show_student(student_query)  # 显示查询结果
            student_query.clear()
            input_mark = input("是否继续查询？（y/n）:")
            if input_mark == "y":
                mark = True
            else:
                mark = False
        else:
            print("暂未保存数据信息...")
            return


def __show_student(student_list):
    if not student_list:
        print("(o@.@o) 无数据信息 (o@.@o) \n")
        return
    format_title = "{:^6}{:^12}\t{:^8}\t{:^10}\t{:^10}\t{:^10}"
    print(format_title.format("ID", "名字", "英语成绩", "Python成绩", "C语言成绩", "总成绩"))  # 按指定格式显示标题
    format_data = "{:^6}{:^12}\t{:^8}\t{:^10}\t{:^10}\t{:^20}"
    for info in student_list:  # 通过for循环将列表中的数据全部显示出来
        print(format_data.format(info.get("id"), info.get("name"), str(info.get("english")), str(info.get("python")),
                                 str(info.get("c")), str(info.get("english") + info.get("python") +
                                                         info.get("c")).center(12)))


def delete():
    show()
    mark = True  # 标记是否循环
    while mark:
        student_id = input("请输入要删除的学生ID：")
        if student_id != "":  # 判断是否输入要删除的学生
            if os.path.exists(filename):
                with open(filename, "r") as f:  # 打开文件
                    student_old = f.readlines()  # 读取全部内容

            else:
                student_old = []

            is_del = False  # 标记是否删除
            if student_old:  # 如果存在学生信息
                with open(filename, "w") as f:  # 重写
                    for s in student_old:
                        d = dict(eval(s))  # 字符串转字典
                        if d["id"] != student_id:
                            f.write(str(d) + "\n")  # 将一条学生信息写入文件
                        else:
                            is_del = True  # 标记已经删除

                    if is_del:
                        print("ID为%s的学生信息已经被删除..." % student_id)
                    else:
                        print("没有找到ID为%s的学生信息..." % student_id)
            else:  # 不存在学生信息
                print("无学生信息")
                break  # 退出循环

            show()  # 显示全部学生信息
            input_mark = input("是否继续删除？（y/n）:")
            if input_mark == "y":
                mark = True  # 继续删除
            else:
                mark = False


def modify():
    show()
    mark = True
    while mark:
        if os.path.exists(filename):
            with open(filename, "r") as f:
                student_list = f.readlines()

            if not student_list:
                print("学生信息为空。")
                break

            with open(filename, "w") as f:
                student_id = input("请输入要修改的学生ID：")
                for s in student_list:
                    s = dict(eval(s))
                    if student_id == s["id"]:
                        s["name"] = input("请输入姓名：")
                        s["english"] = int(input("请输入英语成绩："))
                        s["python"] = int(input("请输入python成绩："))
                        s["c"] = int(input("请输入C语言成绩："))
                        f.write(str(s) + "\n")
                        print("修改成功！")
                    else:
                        f.write(str(s) + "\n")
        input_mark = input("是否继续修改其他学生信息？（y/n）：")
        if input_mark != "y":
            mark = False


def sort():
    show()  # 显示全部学生信息
    if os.path.exists(filename): # 判断文件是否存在
        with open(filename, 'r') as file: # 以只读模式打开文件
            student_old = file.readlines() # 读取全部内容
        student_new = []
        for s in student_old:
            d = dict(eval(s))  # 字符串转字典
            student_new.append(d)  # 将转换后的字典添加到列表中
    else:
        return
    asc = input("请选择（0升序；1降序）：")

    asc_bool = True  # 定义默认降序排序
    if asc == "0":  # 按升序排序
        asc_bool = False
    elif asc == "1":  # 按降序排序
        asc_bool = True
    else:
        print("您的输入有误，请重新输入！")
        sort()
    mode = input("请选择排序方式（1按英语成绩排序；2按Python成绩排序；3按C语言成绩排序；0按总成绩排序）：")
    if mode == "1":  # 按英语成绩排序
        student_new.sort(key=lambda x: int(x["english"]), reverse=asc_bool)
    elif mode == "2":  # 按Python成绩排序
        student_new.sort(key=lambda x: int(x["python"]), reverse=asc_bool)
    elif mode == "3":  # 按C语言成绩排序
        student_new.sort(key=lambda x: x["c"], reverse=asc_bool)
    elif mode == "0":  # 按总成绩排序
        student_new.sort(key=lambda x: x["english"] + x["python"] + x["c"], reverse=asc_bool)
    else:
        print("您的输入有误，请重新输入！")
        sort()
    __show_student(student_new)  # 显示排序结果


def total():
    if os.path.exists(filename):
        with open(filename, 'r') as f:  # 打开文件
            student_old = f.readlines()  # 读取全部内容
            if student_old:
                print("一共有 %d 名学生！" % len(student_old))  # 统计学生人数
            else:
                print("还没有录入学生信息！")
    else:
        print("暂未保存数据信息...")


def show():
    student_new = []
    if os.path.exists(filename):  # 判断文件是否存在
        with open(filename, 'r') as rfile:  # 打开文件
            student_old = rfile.readlines()  # 读取全部内容
        for s in student_old:
            student_new.append(eval(s))  # 将找到的学生信息保存到列表中
        if student_new:
            __show_student(student_new)
    else:
        print("暂未保存数据信息...")


def __save(student):  # 将学生信息保存到文件
    try:
        students_txt = open(filename, "a")  # 以追加模式打开
    except FileNotFoundError:
        students_txt = open(filename, "w")  # 文件不存在，创建文件并打开

    for info in student:
        students_txt.write(str(info) + "\n")  # 按行存储，添加换行符

    students_txt.close()


if __name__ == "__main__":
    main()
